from array import array
import sets
from gameflags import *
from OpenGL.GL import *
import Image

class mesh(object):
    def __init__(self, name):
        self.name = name
        self.vertices = []
        self.faces = []
        self.position = [0,0,0]
        self.rotation = [0,0,0]
        self.scale = [1,1,1]
        self.renderType = sets.Set([POLYGONS])
        self.events = []
        self.logicBricks = []
        self.selected = False
        self.displayID = None
        self.pickyCol = None
        self.allocateEvents()
        
    def registerEvent(self,definition):
        self.events.append(definition)
        
    def allocateEvents(self):
        """ 
        Provides an interface to register events locally based
        on a mesh
        """
        
    def setScale(self,coords):
        self.scale = coords
        
    def setRotation(self, axis, degree):
        if axis == 'x':
            self.rotation[0] += degree
        elif axis == 'y':
            self.rotation[1] += degree
        elif axis == 'z':
            self.rotation[2] += degree
            
    def setPosition(self,coords):
        self.position = coords
        
    def allocateStructure(self,verts,faces,uvs=None):
        for v in verts:
            self.vertices.append(vertex(v))
        for f in faces:
            self.faces.append(face(f))
        if uvs != None:
            for i,uv_ in enumerate(uvs):
                self.vertices[i].uv.append(uv(vector(uv_)))
    
    def assignTexture(self,tid):
        for face in self.faces:
            face.textureID = tid
        


class face:
    def __init__(self,vertices):
        self.mapping = vertices
        self.textureID = None

class vertex:
    def __init__(self,position):
        """
        Each vertex hold data for animation support.
        Coordinate - Position of Vertex
        Weight - Skeleton Assignment
        """
        self.position = [vector(position)]
        self.uv = []
        self.weight = []
        self.color = []
        
    def __repr__(self):
        return str(self.position[0].tolist())
    
    def __getitem__(self,i):
        return self.position[0][i]

class uv:
    def __init__(self,vec):
        self.s = vec[0]
        self.t = vec[1]
        
    def __getitem__(self,i):
        return vector([self.s,self.t])[i]
    
    def __repr__(self):
        return str([self.s,self.t])
    
    def __setitem__(self,i,value):
        vec = vector([self.s,self.t])
        vec[i] = value
        self.s = vec[0]
        self.t = vec[1]

class vector(array):
    def __init__(self,position):
        for value in position:
            self.append(value)
        
    def __new__(cls,*args):
        return super(vector,cls).__new__(cls,'f')
    
    def __repr__(self):
        return str(self.tostring())
    
    def sizeOf(self):
        """Returns the number of bytes used"""
        return self.itemsize*len(self.tolist())

class weight(dict):
    def __init__(self,value={}):
        dict.__init__(self,value)

class cube(mesh):
    def __init__(self,name):
        super(cube, self).__init__(name)
        vertices = [[1.000000, 1.000000, -1.000000], 
                         [1.000000, -1.000000, -1.000000], 
                         [-1.000000, -1.000000, -1.000000], 
                         [-1.000000, 1.000000, -1.000000], 
                         [1.000000, 0.999999, 1.000000], 
                         [0.999999, -1.000001, 1.000000], 
                         [-1.000000, -1.000000, 1.000000], 
                         [-1.000000, 1.000000, 1.000000]]
        faces = [[4, 0, 7],[0, 3, 7],[2, 6, 7], 
                      [2, 7, 3],[1, 5, 2],[5, 6, 2], 
                      [0, 4, 1],[4, 5, 1],[4, 7, 6], 
                      [4, 6, 5],[0, 1, 2],[0, 2, 3]]
        uv = [[1.0, 0.3220687210559845], 
                   [0.84381389617919922, 0.011950600892305374], 
                   [0.08482658863067627, 0.0], 
                   [0.24101285636425018, 0.31011813879013062], 
                   [0.91517370939254761, 1.0], 
                   [0.75898712873458862, 0.68988186120986938], 
                   [0.0, 0.67793136835098267], 
                   [0.15618626773357391, 0.98804944753646851]]
        self.allocateStructure(vertices,faces,uv)

class plane(mesh):
    def __init__(self,name):
        super(plane, self).__init__(name)
        vertices = [[1.000000, 1.000000, -1.000000], 
                    [1.000000, -1.000000, -1.000000], 
                    [-1.000000, -1.000000, -1.000000], 
                    [-1.000000, 1.000000, -1.000000]]
        faces = [[0, 1, 2],[2, 3, 0]]
        uv = [[1.0, 1.0], 
              [1.0, 0.0], 
              [0.0, 1.0], 
              [0.0, 0.0]]
        self.allocateStructure(vertices,faces,uv)
